.\" Copyright (c) 2007 Eric Anderson <anderson@FreeBSD.org>
.\" Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
.\" Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd August 6, 2025
.Dt EXPAND_NUMBER 3
.Os
.Sh NAME
.Nm expand_number ,
.Nm expand_unsigned
.Nd parse a number from human readable form
.Sh LIBRARY
.Lb libutil
.Sh SYNOPSIS
.In libutil.h
.Ft int
.Fo expand_number
.Fa "const char *buf" "int64_t *num"
.Fc
.Ft int
.Fo expand_unsigned
.Fa "const char *buf" "uint64_t *num"
.Fc
.Sh DESCRIPTION
The
.Fn expand_number
function parses the number in the string pointed to by its
.Fa buf
argument and stores the number it represents as a signed 64-bit
quantity in the location pointed to by its
.Fa *num
argument.
.Pp
The
.Fn expand_unsigned
function is similar to
.Fn expand_number ,
but accepts only positive numbers in the range
.Bq 0, Ns Dv UINT64_MAX .
.Pp
Both functions interpret the input
.Dq -0
as 0.
.Pp
The input string must consist of a decimal number, optionally preceded
by a
.Sq +
or
.Sq -
sign, and optionally followed, without intervening whitespace, by a
suffix indicating a power-of-two multiplier to apply.
Any amount of whitespace at the beginning of the string will be
ignored.
.Pp
Recognized suffixes are:
.Bl -column "Suffix" "Description" "1000000000000000000" -offset indent
.It Sy "Suffix" Ta Sy "Description" Ta Sy "Multiplier"
.It Li K Ta No kilo Ta 1,024
.It Li M Ta No mega Ta 1,048,576
.It Li G Ta No giga Ta 1,073,741,824
.It Li T Ta No tera Ta 1,099,511,627,776
.It Li P Ta No peta Ta 1,125,899,906,842,624
.It Li E Ta No exa  Ta 1,152,921,504,606,846,976
.El
.Pp
For historical reasons, the
.Fn expand_number
function accepts and ignores a single
.Dq B
suffix at the end of the
.Fa buf
string (i.e.
.Dq 5b
is interpreted as 5, and
.Dq 5kb
is interpreted as 5,120).
However, the usage of this suffix is discouraged.
.Pp
For backward compatibility reasons, if the compiler supports generic
selection, a macro is provided which automatically replaces calls to
.Fn expand_number
with calls to
.Fn expand_unsigned
if the type of the actual
.Va num
argument is compatible with
.Vt uint64_t * .
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
The
.Fn expand_number
and
.Fn expand_unsigned
functions will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The given string does not contain a valid number.
.It Bq Er EINVAL
An unrecognized suffix was encountered.
.It Bq Er ERANGE
The given string represents a number which does not fit into an
.Vt int64_t
(for
.Fn expand_number )
or
.Vt uint64_t
(for
.Fn expand_unsigned ) .
.El
.Sh SEE ALSO
.Xr humanize_number 3
.Sh HISTORY
The
.Fn expand_number
function first appeared in
.Fx 6.3 .
The original implementation did not handle negative numbers correctly,
and it was switched to taking a
.Vt uint64_t *
and accepting only positive numbers in
.Fx 9.0 .
The
.Fn expand_unsigned
function was added,
and
.Fn expand_number
switched back to
.Vt int64_t * ,
in
.Fx 15.0 .
